/*
* Copyright 2010 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/

package org.etherframework.core
{
	import org.etherframework.core.util.ListenerUtil;
	
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	
	import mx.core.IUIComponent;
	
	public class DisplayDispatcher implements IEventDispatcher
	{
		private var sm:IEventDispatcher;
		
		private var app:IEventDispatcher;
		
		private var dispatcher:IEventDispatcher;
		
		private var listeners:Array;
		
		public function DisplayDispatcher(sm:IEventDispatcher, app:IEventDispatcher)
		{
			this.sm = sm;
			this.app = app;
			
			listeners = [];
			
			dispatcher = isInitialized(app) ?  sm : app;
			
			if (dispatcher == app)
			{
				app.addEventListener(Event.ADDED_TO_STAGE, appAddedToStage, false, 200);
			}
		}
		
		public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
			
			if (dispatcher == app)
			{
				listeners.push(new ListenerInfo(type, listener, useCapture, priority, useWeakReference));
			}
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			dispatcher.removeEventListener(type, listener, useCapture);
		}
		
		public function dispatchEvent(event:Event):Boolean
		{
			return dispatcher.dispatchEvent(event)
		}
		
		public function hasEventListener(type:String):Boolean
		{
			return dispatcher.hasEventListener(type);
		}
		
		public function willTrigger(type:String):Boolean
		{
			return dispatcher.willTrigger(type);
		}
		
		public function removeAllEventListeners():void
		{
			
		}
		
		private function appAddedToStage(event:Event):void
		{
			var max:int = listeners.length;
			var listenerInfo:ListenerInfo;
			
			for (var i:int = 0; i < max; ++i)
			{
				listenerInfo = listeners[i];
				app.removeEventListener(listenerInfo.type, listenerInfo.listener, listenerInfo.useCapture);
				sm.addEventListener(listenerInfo.type, listenerInfo.listener, listenerInfo.useCapture, listenerInfo.priority, listenerInfo.useWeakReference);
			}
			
			listeners = null;
			dispatcher = sm;
			app.removeEventListener(Event.ADDED_TO_STAGE, appAddedToStage);
		}
		
		private function isInitialized(obj:Object):Boolean
		{
			return ((app is IUIComponent) && ("initialized" in app)) ? app["initialized"] : false;
		}
		
	}
}

final class ListenerInfo
{
	public var type:String;
	
	public var listener:Function;
	
	public var useCapture:Boolean;
	
	public var priority:int;
	
	public var useWeakReference:Boolean;
	
	public function ListenerInfo(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false)
	{
		this.type = type;
		this.listener = listener;
		this.useCapture = useCapture;
		this.priority = priority;
		this.useWeakReference = useWeakReference;
	}
}